package 时间转换入库方式;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import utils.DateUtil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created by Wolfe
 * on 2016/9/29.
 */
@Slf4j
public class DateUtil_incentive {

    private DateUtil_incentive() {

    }

    /**
     * 锁对象
     */
    private static final Object LOCK = new Object();
    /**
     * 存放不同的日期模板格式的sdf的Map
     */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<>();
    /**
     * 日期时间格式 *
     */

    public static final String DATE_PATTERN = "yyyyMMdd";
    public static final String FULL_PATTERN = "yyyyMMddHHmmss";
    public static final String FULL_PATTERNS = "yyyyMMddHHmmssSSS";
    public static final String PART_PATTERN = "yyMMddHHmmss";
    public static final String YEAR_DATE = "yyyy-MM-dd HH:mm";
    public static final String DATE_PATTERN1 = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_PATTERN2 = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String YEAR_MONTH_PATTERN = "yyyy-MM";
    public static final String DATE_PATTERN3 = "yyyy-MM-dd";
    public static final String DATE_YEAR_MONTH_DAT = "yyyy.MM.dd";
    public static final String YEAR_MONTH = "yyyyMM";
    public static final String DD = "dd";



    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static LocalDateTime toLocalDate(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    public static String yearMonth(int year, int month) {
        return LocalDate.of(year, month, 1)
                .format(DateTimeFormatter.ofPattern(YEAR_MONTH_PATTERN));
    }

    public static String firstDayOfMonth(int year, int month) {
        return LocalDate.of(year, month, 1)
                .format(DateTimeFormatter.ofPattern(DATE_PATTERN3));
    }

    public static String getFirstDayOfMonth(LocalDate localDate) {
        return LocalDate.of(localDate.getYear(), localDate.getMonthValue(), 1).format(DateTimeFormatter.ofPattern(DATE_PATTERN3));
    }

    public static String getLastDayOfMonth(LocalDate localDate) {
        return localDate.with(TemporalAdjusters.lastDayOfMonth()).format(DateTimeFormatter.ofPattern(DATE_PATTERN3));
    }

    public static String getMonthOfDay(LocalDate localDate, int dayOfMonth) {
        return localDate.withDayOfMonth(dayOfMonth).format(DateTimeFormatter.ofPattern(DATE_PATTERN3));
    }
    /**
     * 时间格式转换
     *
     * @param date          时间字符串
     * @param originPattern 原时间格式
     * @param targetPattern 新的时间格式
     * @return
     * @throws ParseException
     */
    public static String convert(String date, String originPattern, String targetPattern){
        Date originDate = null;
        try {
            originDate = parse(date, originPattern);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return format(originDate, targetPattern);
    }

    /**
     * 源日期和（目标日期加上毫秒数）比较大小， 大则返回false ，小返回true
     *
     * @param src    源日期
     * @param target 目的日期
     * @param second 秒数
     * @return 成功，失败
     */
    public static boolean compareDateForSecond(Date src, Date target, int second) {
        Calendar targetTime = Calendar.getInstance();
        targetTime.setTime(target);
        targetTime.add(Calendar.SECOND, second);
        Calendar srcTime = Calendar.getInstance();
        srcTime.setTime(src);
        return srcTime.compareTo(targetTime) <= 0;
    }

    public static String getCurrentAfter(int minute) {
        Calendar targetTime = Calendar.getInstance();
        targetTime.setTime(new Date());
        targetTime.add(Calendar.MINUTE, minute);
        return format(targetTime.getTime(), DateUtil.FULL_PATTERN);
    }

    public static String getCurrentAfter(int minute, String dataPattern) {
        Calendar targetTime = Calendar.getInstance();
        targetTime.setTime(new Date());
        targetTime.add(Calendar.MINUTE, minute);
        return format(targetTime.getTime(), dataPattern);
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static String getCurrent() {
        return format(new Date(), DateUtil.FULL_PATTERN);

    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static String getCurrent(String format) {
        return format(new Date(), format);

    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static String getCurrents() {
        return format(new Date(), DateUtil.FULL_PATTERNS);

    }

    /**
     * 精确到毫秒
     *
     * @return
     */
    public static String fPatterns() {
        return format(new Date(), DateUtil.FULL_PATTERNS);
    }

    /**
     * 格式
     *
     * @return
     */
    public static String getPartPattern() {
        return format(new Date(), DateUtil.PART_PATTERN);
    }

    public static String getCurrentForMonth() {
        return format(new Date(), DateUtil.DATE_PATTERN);
    }

    /**
     * 获取当前时间格式为
     * yyyy-MM-dd
     */
    public static String getCurrentFormat() {
        return format(new Date(), DateUtil.YEAR_DATE);
    }

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern
     * @return
     */
    private static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);
        // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
        if (tl == null) {
            synchronized (LOCK) {
                tl = sdfMap.get(pattern);
                if (tl == null) {
                    tl = new ThreadLocal<SimpleDateFormat>() {
                        @Override
                        protected SimpleDateFormat initialValue() {
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern, tl);
                }
            }
        }

        return tl.get();
    }

    /**
     * 使用线程容器来获取SimpleDateFormat
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String format(Date date, String pattern) {
        if (date == null) {
            return null;
        }
        return getSdf(pattern).format(date);
    }

    public static Date parse(String dateStr, String pattern) throws ParseException {
        return getSdf(pattern).parse(dateStr);
    }

    public static Date parseDate(String dateStr, String pattern) {
        try {
            return parse(dateStr, pattern);
        } catch (ParseException e) {
            log.error("ParseException：", e);
        }
        return null;
    }


    /**
     * 获取前一天的日期
     *
     * @return
     */
    public static String getLastDay(Date date, String format, int day) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -day);
        date = calendar.getTime();
        String d = sdf.format(date);
        return d;
    }

    /**
     * 获取前一年的日期
     *
     * @return
     */
    public static String getLastYear(Date date, String format, int year) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        calendar.add(Calendar.YEAR, -year);
        date = calendar.getTime();
        String d = sdf.format(date);
        return d;
    }

    /**
     * 响应时间
     *
     * @param startDate
     * @return
     */
    public static long resDate(long startDate) {
        long endDate = System.currentTimeMillis();
        long date = endDate - startDate;
        return date;
    }

    public static boolean isWorkingTime(String startTime, String endTime) {
        Boolean isTime = true;
        Date now = new Date();
        try {
            Calendar cal1 = Calendar.getInstance();
            Calendar cal2 = Calendar.getInstance();
            Calendar cal3 = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            cal1.setTime(now);
            String year = sdf.format(now).substring(0, 8);
            cal2.setTime(sdf.parse(year + startTime));
            cal3.setTime(sdf.parse(year + endTime));
            if (cal2.before(cal1) && cal3.after(cal1)) {
                isTime = false;
            }
        } catch (ParseException e) {
            log.error("ParseException：", e);
        }
        return isTime;
    }

    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        System.out.println(nowTime);
        System.out.println(startTime);
        System.out.println(endTime);
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * String转Date
     *
     * @param
     * @throws ParseException
     */
    public static Date stringToDate(String str, String pattern) {
        DateFormat format = new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            log.error("ParseException：", e);
        }
        return date;
    }
    /**
     * 时间格式转换
     *
     * @param date          时间字符串
     * @param targetPattern 新的时间格式
     * @return
     * @throws ParseException
     */
    public static String convert(Date date, String targetPattern) {
        try {
            return format(date, targetPattern);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 当前时间+count
     *
     * @param count
     * @return
     */
    public static String getDate(Integer count, String pattern) {
        SimpleDateFormat sf = new SimpleDateFormat(pattern);//fullPattern
        Calendar c = Calendar.getInstance();
        log.info("当前日期:" + sf.format(c.getTime()));
        c.add(Calendar.DAY_OF_MONTH, count);
        return sf.format(c.getTime());
    }

    /**
     * 当前时间+count
     *
     * @param count
     * @return
     */
    public static Date getDate(Integer count) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, count);
        return c.getTime();
    }

    /**
     * 当前时间+count
     *
     * @param count
     * @return
     */
    public static String getDate(String date, Integer count, String pattern) {
        SimpleDateFormat sf = new SimpleDateFormat(pattern);//fullPattern
        Calendar c = Calendar.getInstance();
        try {
            c.setTime(sf.parse(date));
        } catch (ParseException e) {
            log.error("msg：", e);
        }
        log.info("日期:" + sf.format(c.getTime()));
        c.add(Calendar.DAY_OF_MONTH, count);
        return sf.format(c.getTime());
    }

    /**
     * 指定日期+count
     *
     * @param count
     * @return
     */
    public static Date getDate(String date, Integer count) {
        SimpleDateFormat sf = new SimpleDateFormat(DateUtil.DATE_PATTERN1);
        Calendar c = Calendar.getInstance();
        try {
            c.setTime(sf.parse(date));
        } catch (ParseException e) {
            log.error("msg：", e);
        }
        c.add(Calendar.DAY_OF_MONTH, count);
        return c.getTime();
    }

    /**
     * date1小于date2返回-1，date1大于date2返回1，相等返回0
     *
     * @param date2
     * @return
     */
    public static int contrastDate(String date2) {
        SimpleDateFormat sf = new SimpleDateFormat(FULL_PATTERN);
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 0);
        Date d1 = stringToDate(sf.format(c.getTime()), FULL_PATTERN);
        if (d1 == null) {
            return 0;
        }
        Date d2 = stringToDate(date2, FULL_PATTERN);
        return d1.compareTo(d2);
    }


    /**
     * 计算两个时间相差天数
     *
     * @param date1
     * @param date2
     */
    public static int daysOfTwo(String date1, String date2) {
        return timesOfTwo(date1, date2, TimeUnit.DAYS);
    }

    /**
     * 计算两个时间相差时间
     *
     * @param date1
     * @param date2
     */
    public static int timesOfTwo(String date1, String date2, TimeUnit timeUnit) {
        long times = -1L, unit;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN1);
            if (StringUtils.isEmpty(date1)) {
                Calendar c = Calendar.getInstance();
                date1 = sdf.format(c.getTime());
            }
            Date fDate = sdf.parse(date1);
            Date oDate = sdf.parse(date2);

            if (TimeUnit.DAYS == timeUnit) {
                unit = 1000 * 3600 * 24;
            } else if (TimeUnit.MINUTES == timeUnit) {
                unit = 1000 * 60;
            } else if (TimeUnit.HOURS == timeUnit) {
                unit = 1000 * 3600;
            } else if (TimeUnit.SECONDS == timeUnit) {
                unit = 1000;
            } else {
                unit = 1;
            }
            times = (oDate.getTime() - fDate.getTime()) / unit;
        } catch (Exception e) {
            log.error("时间计算异常：", e);
        }
        return (int) times;
    }

    /**
     * 将20190101转换为2019年1月1日
     *
     * @param dateTime
     * @return
     */
    public static String getDatePattern(String dateTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
        String str = "";
        try {
            Date date = sdf1.parse(dateTime);

            str = sdf.format(date);
        } catch (ParseException e) {
            log.error("ParseException：", e);
        }
        return str;
    }

    /**
     * 获取当前时间count年的时间
     *
     * @param count
     * @return
     */
    public static String getDateYear(int count) {
        SimpleDateFormat format = new SimpleDateFormat(FULL_PATTERN);
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, count);
        Date y = c.getTime();
        System.out.println(y);
        String year = format.format(y);
        System.out.println("过去一年：" + year);
        return year;
    }

    /**
     * 获取某一年的第一天
     *
     * @param dataStr
     * @param dateFormat
     * @param resultDateFormat
     * @return
     * @throws ParseException
     */
    public static String getFirstOfYear(String dataStr, String dateFormat, String resultDateFormat) {
        //获取当前第一天：
        Calendar c = Calendar.getInstance();
        try {
            c.setTime(new SimpleDateFormat(dateFormat).parse(dataStr));
        } catch (ParseException e) {
        }
        c.add(Calendar.YEAR, 0);
        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_YEAR, 1);
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        String first = new SimpleDateFormat(resultDateFormat).format(c.getTime());
        return first;
    }

    public static Date getFirstOfYear(Date date) {
        //获取当前第一天：
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, 0);
        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_YEAR, 1);
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 获取某一个月的第一天
     *
     * @param dataStr
     * @param dateFormat
     * @param resultDateFormat
     * @return
     * @throws ParseException
     */
    public static String getFirstOfMonth(String dataStr, String dateFormat, String resultDateFormat) {
        //获取当前月第一天：
        Calendar c = Calendar.getInstance();
        try {
            c.setTime(new SimpleDateFormat(dateFormat).parse(dataStr));
        } catch (ParseException e) {
        }
        c.add(Calendar.MONTH, 0);
        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        String first = new SimpleDateFormat(resultDateFormat).format(c.getTime());
        return first;
    }

    /**
     * 获取某一个周的第一天
     *
     * @param dataStr
     * @param dateFormat
     * @param resultDateFormat
     * @return
     * @throws ParseException
     */
    public static String getFirstOfWeek(String dataStr, String dateFormat, String resultDateFormat) {
        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(new SimpleDateFormat(dateFormat).parse(dataStr));
        } catch (ParseException e) {
        }
        int d = 0;
        if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
            d = -6;
        } else {
            d = 2 - cal.get(Calendar.DAY_OF_WEEK);
        }
        cal.add(Calendar.DAY_OF_WEEK, d);
        // 所在周开始日期
        String firstWeekDay = new SimpleDateFormat(resultDateFormat).format(cal.getTime());
        return firstWeekDay;
    }

    public static String getFirstOfWeek(String resultDateFormat) {
        return getFirstOfWeek(convert(new Date(), DATE_PATTERN1), DATE_PATTERN1, resultDateFormat);
    }

    public static String getFirstOfMonth(String resultDateFormat) {
        return getFirstOfMonth(convert(new Date(), DATE_PATTERN1), DATE_PATTERN1, resultDateFormat);
    }

    public static Date getDataStartTimeOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        return calendar.getTime();
    }

    /**
     * 获取指定日期月份的最后一天
     *
     * @param date
     * @return
     */
    public static Date getMonthEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        int index = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.DATE, (-index));
        return calendar.getTime();
    }

    /**
     * 获取一天的开始时间
     *
     * @param date
     */
    public static Date getStartByDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取一天的结束时间
     *
     * @param date
     */
    public static Date getEndByDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 日期+count
     * @param date
     * @param count
     * @return
     */
    public static Date getDataStartTimeOfMonth(Date date,Integer count) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, count);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        return calendar.getTime();
    }


    public static Date getData(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取前月的最后一天
     * @param pattern
     * @return
     */
    public static String monthEnd(String pattern){
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        Calendar cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        return format.format(cale.getTime());
    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串 格式（MM）
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串 格式（dd）
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        if (null == date) {
            return "";
        }
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

}
